package com.log4jviewer.ui.preferences.additional;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.log4jviewer.Activator;

/**
 * Class represents additional preference page with log color settings and column settings for log table.
 * 
 * @author <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a>
 */
public class AdditionalPreferencePage extends FieldEditorPreferencePage implements
        IWorkbenchPreferencePage {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private static Set<AdditionalPreferencePageListener> listeners = new HashSet<AdditionalPreferencePageListener>();

    private IPreferenceStore store;

    private ColumnModelList columnModelList;

    @Override
    public void init(final IWorkbench workbench) {
        store = Activator.getInstance().getPreferenceStore();
        setPreferenceStore(store);
        setDescription("Additional settings for logviewer log table.");
        columnModelList = new ColumnModelList(store);
    }

    @Override
    protected void createFieldEditors() {
        Composite composite = getFieldEditorParent();
        composite.setLayout(new GridLayout());

        // Log table columns settings
        composeTableColumnSettings(composite);
        logger.info("Log table columns settings were composed.");

        // Log display settings
        composeLogDisplaySettings(composite);
        logger.info("Log display settings were composed.");
    }

    private void composeLogDisplaySettings(final Composite composite) {
        GridLayout gridLayout = new GridLayout();
        Group groupSettings = createGroupSettings(composite, gridLayout, "Log display");
        LogDisplayPreferenceView logDisplayPreferenceView = new LogDisplayPreferenceView();
        logDisplayPreferenceView.addChildControls(groupSettings);
    }

    private void composeTableColumnSettings(final Composite composite) {
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 2;
        Group groupSettings = createGroupSettings(composite, gridLayout, "Log Table columns");
        new ColumnPreferenceView(groupSettings, columnModelList);
    }

    private Group createGroupSettings(final Composite composite, final GridLayout gridLayout, final String title) {
        Group groupSettings = new Group(composite, SWT.NONE);
        groupSettings.setText(title);
        groupSettings.setLayout(gridLayout);
        GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
        gridData.horizontalSpan = 2;
        groupSettings.setLayoutData(gridData);
        return groupSettings;
    }

    private void notifyColumnPrefsObservers() {
        final ColumnModel[] columnItems = columnModelList.getColumnItems();
        // Notify listeners that data in column preferences or in display log preferences changed.
        notifyListeners(this, columnItems);
    }

    public static void notifyListeners(final AdditionalPreferencePage event, final ColumnModel[] columnItems) {
        for (AdditionalPreferencePageListener listener : listeners) {
            listener.handleAdditionalPreferenceEvent(event, columnItems);
        }
    }

    public static void addListener(final AdditionalPreferencePageListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }

    public static void removeListener(final AdditionalPreferencePageListener listener) {
        listeners.remove(listener);
    }

    @Override
    protected void performApply() {
        super.performApply();
        notifyColumnPrefsObservers();
        LogDisplayPreferences.getLogColorSettings().saveSettings();
    }

    @Override
    public boolean performOk() {
        boolean isSaved = super.performOk();
        notifyColumnPrefsObservers();
        LogDisplayPreferences.getLogColorSettings().saveSettings();
        return isSaved;
    }
}
